<?php

class Player {

	private $id;
	private $name;
	private $password;
	private $email;
	private $localisation;
	private $newsletterThreshold;


	
	public function __construct(){	
	}



	/*
	 * Sauvegarde les informations d'un compte joueur.
	 *
	 * Retourne TRUE en cas de succès.
	 * Lance une exception en cas d'erreur.
	 */
	public function save(){

		$mysql = MySQL::getInstance();
		
		/* 
		 * Le joueur n'est pas encore connecté,
		 * cette sauvegarde est une inscription.
		 */
		if(!isset($this->id)){
	
			$query = sprintf(
				"INSERT INTO	players
				(
					name,
					email,
					password,
					localisation,
					newsletter_threshold
				)
				VALUES (
					'%s',
					'%s',
					'%s',
					'%s',
					%d
				);",
				$mysql->real_escape_string($this->name),
				$mysql->real_escape_string($this->email),
				hash('sha256', $this->password),
				$mysql->real_escape_string($this->newsletterThreshold),
				40				
			);
			
			$mysql->query($query);
		
			if($mysql->error){
				throw new Exception("La création du compte a provoqué une ".
									"erreur SQL. ".$mysql->error.".");
			}
			
			if($mysql->affected_rows == 0){
				throw new Exception("La création du compte n'a crée aucune ".
									"entrée dans la base de données.");
			}
			elseif($mysql->affected_rows > 1){
				throw new Exception("La création du compte a crée plusieurs ".
									"entrées dans la base de données.");
			}		
		}
		
		/*
		 * Le joueur est connecté, on sauvegarde ses
		 * informations en base de données.
		 */
		else {

			$query = sprintf(
				"UPDATE	players
				SET		email					= '%s',
						password 				= '%s',
						localisation			= '%s',
						newsletter_threshold	= %d
				WHERE	id						= %d;",
				$mysql->real_escape_string($this->email),
				hash('sha256', $this->password),
				$mysql->real_escape_string($this->localisation),
				$this->newsletterThreshold,
				$this->id
			);
			
			$mysql->query($query);
		
			if($mysql->error){
				throw new Exception("La création du compte a provoqué une ".
									"erreur SQL. ".$mysql->error.".");
			}
			
			if($mysql->affected_rows > 1){
				throw new Exception("La création du compte a crée plusieurs ".
									"entrées dans la base de données.");
			}

		}

		return TRUE;
	}
	
	
	
	/*
	 * Supprime un compte joueur.
	 *
	 * Retourne TRUE en cas de succès.
	 * Lance une exception en cas d'erreur.
	 */
	public function delete(){
		
		$mysql = MySQL::getInstance();
		
		$query = sprintf(
			"UPDATE	players
			SET		status	= 0
			WHERE	id		= %d",
			$this->id
		);
		$mysql->query($query);
		
		if($mysql->error){
			throw new Exception("La suppresion du compte a provoqué une erreur ".
								"SQL. ".$mysql->error.".");
		}
		
		if($mysql->affected_rows == 0){
			throw new Exception("La suppresion du compte n'a affecté aucune ".
								"entrée dans la base de données.");
		}
		elseif($mysql->affected_rows > 1){
			throw new Exception("La suppresion du compte a affecté plusieurs ".
								"entrées dans la base de données.");
		}
		
		return TRUE;
	}



	/*
	 * Charge les informations d'un joueur.
	 *
	 * Retourne l'objet joueur en cas de succès.
	 * Retourne NULL si aucun joueur ne correspond.
	 * Lance une exception en cas d'erreur.
	 */
	public function load(){
		
		$mysql = MySQL::getInstance();
		
		/* Le joueur est déjà connecté. */
		if(!isset($this->id)){
			$query = sprintf(
				"SELECT	id,
						name,
						email,
						localisation,
						newsletter_threshold
				FROM	players
				WHERE	name		= '%s'
				AND		password	= '%s'
				AND		status		!= %d;",
				$mysql->real_escape_string($this->name),
				hash('sha256', $this->password),
				0
			);
		}
		/* Le joueur se connecte. */
		else {
			$query = sprintf(
				"SELECT	id,
						name,
						email,
						localisation,
						newsletter_threshold
				FROM	players
				WHERE	id		= %d
				AND		status	!= %d;",
				$this->id,
				0
			);
		}
		
		$ressource = $mysql->query($query);
		
		if($mysql->error){
			throw new Exception("La connexion a provoqué une erreur ".
								"SQL. \"".$mysql->error."\".");
		}
		
		if($ressource->num_rows > 1){
			throw new Exception("La connexion a renvoyé plus d'une entrée ");
		}
		elseif($ressource->num_rows == 0){
			return FALSE;
		}
		
		$result = $ressource->fetch_object();

		$this->id					= $result->id;
		$this->name					= $result->name;
		$this->email				= $result->email;
		$this->localisation			= $result->localisation;
		$this->newsletterThreshold	= $result->newsletter_threshold;

		return TRUE;
	}
	
		
	
	/*
	 * Édite les préférences de l'utilisateur 
	 * à propos de la lettre d'informations.
	 *
	 * Accepte un seuil d'importance des messages à envoyer.
	 * Retourne TRUE en cas de succès.
	 * Lance une exception en cas d'erreur.
	 */
	public function editPreferencesOfNewsletter($threshold){
		
		$mysql = MySQL::getInstance();
		
		$query = sprintf(
			"UPDATE	players
			SET		newsletter_threshold = %d
			WHERE	id = %d;",
			$threshold,
			$this->id
		);
		
		$mysql->query($query);
		
		if($mysql->error){
			throw new Exception("L'édition des préférences de la lettre d'".
								"information provoqué une erreur SQL. ".
								$mysql->error.".");
		}
		
		if($mysql->affected_rows == 0){
			throw new Exception("L'édition des préférences de la lettre d'".
								"information n'a affecté aucune entrée dans ".
								"la base de données.");
		}
		elseif($mysql->affected_rows > 1){
			throw new Exception("L'édition des préférences de la lettre d'".
								"information a affecté plusieurs entrées ".
								"dans la base de données.");
		}
		
		return TRUE;
	}
	
	
	
	/*
	 * Change l'adresse email du compte.
	 *
	 * Accepte la nouvelle adresse email.
	 * Returne TRUE en cas de succès.
	 * Lance une exception en cas d'erreur.
	 * Lance la procédure de changement de mot de passe.
	 */
	public function changeEmail(){
	}
	
	
	
	/*
	 * Change le mot de passe du compte.
	 *
	 * Genère un nouveau mot de passe et 
	 * l'envoie à l'adresse email du compte.
	 * Retourne TRUE en cas de succès.
	 * Lance une exception en cas d'erreur.
	 */
	public function changePassword(){
		
	}
	 
	 
	 
	/*
	 * Enregistre l'objet et ses modifications.
	 *
	 * Renvoie TRUE en cas de succès.
	 * Lance une exception en cas d'erreur.
	 */
	public function saveInformations(){
	}



	/*
	 * Génère un mot de passe mémorisable.
	 *
	 * Retourne ce mot de passe.
	 */
	public function generatePassword(){
		
		$stringLength = rand(4, 8);
		
		$consonants = array('b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm', 'n', 
		'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'z');

		/* Les voyelles courantes sont dupliquées. */
		$vowels = array('a', 'a', 'a', 'e', 'e', 'e', 'i', 'i', 'o', 'o', 'u', 
		'u', 'y');

		$password = '';
		for($i = 1; $i < $stringLength; $i++){
			$password .=
				($i%2 == 0)
					? $consonants[rand(0, count($consonants) - 1)]
					: $vowels[rand(0, count($vowels) - 1)]
			;
		}
		$password .= '_' . rand(100, 999);

		return $password;

	}



	/*
	 * Vérifie la validité d'un nom de compte.
	 *
	 * Accepte un nom.
	 * Renvoie TRUE en cas de validité.
	 * Renvoie FALSE sinon.
	 */
	public function isValidName($name){

		$pattern = "#^[A-Za-zéè]+[' -]?[A-Za-zéè]*$#";
		if(preg_match($pattern, $name) && strlen($name) <= 25){
			return TRUE;	
		}
		return FALSE;
	}



	/*
	 * Vérifie la validité d'une adresse email.
	 *
	 * Accepte une adresse email.
	 * Renvoie TRUE en cas de validité.
	 * Renvoie FALSE sinon.
	 */	
	public function isValidEmail($email){

		$pattern = "#^[a-z0-9._-]+@[a-z0-9._-]{2,}\.[a-z]{2,4}$#";
		if(preg_match($pattern, $email)){
			return TRUE;
		}
		return FALSE;
	}
	
	
	
	/*
	 * Vérifie si ce seuil d'envoi de newsletter est valide.
	 *
	 * Accepte un seuil.
	 * Renvoie TRUE si le seul est valide.
	 * Renvoie FALSE sinon.
	 */
	public function isValidNewsletterThreshold($threshold){
		
		$validThresholds = array(0, 10, 20, 30, 40);
		
		if(in_array($threshold, $validThresholds)){
			return TRUE;	
		}
		
		return FALSE;
	}
	
	
	/* 
	 * Getters & setters
	 */
	public function getId(){
		return $this->id;
	}
	
	
	public function getName(){
		return $this->name;
	}
	
	public function setName($value){
		$this->name = $value;
	}

	
	public function setPassword($value){
		$this->password = $value;	
	}
	
	
	public function getEmail(){
		return $this->email;
	}

	public function setEmail($value){
		$this->email = $value;
	}
	
	
	public function getLocalisation(){
		return $this->localisation;
	}

	public function setLocalisation($value){
		$this->localisation = $value;
	}
	
	
	public function getNewsletterThreshold(){
		return $this->newsletterThreshold;	
	}
	
	public function setNewsletterThreshold($value){
		$this->newsletterThreshold = $value;
	}
	
	
}

?>